
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System.Threading.Tasks;

namespace DataTransformationTasks.BaseDriver;

public class Handler
{
    protected ILogger Logger { get; set; } = NullLogger.Instance;

    protected Handler(Machine machine)
    {
        Logger = LoggerFactory.CreateLogger(GetType().FullName);
        Machine = machine;
    }

    public Machine Machine { get; }

    public virtual Task<dynamic> CreateAsync()
    {
        return Task.FromResult<dynamic>(null);
    }

    public async Task OnDataArrivalInternalAsync(Veneers veneers, Veneer veneer)
    {
        var beforeRet = await BeforeDataArrivalAsync(veneers, veneer);
        var onRet = await OnDataArrivalAsync(veneers, veneer, beforeRet);
        await AfterDataArrivalAsync(veneers, veneer, onRet);
    }

    protected virtual Task<dynamic> BeforeDataArrivalAsync(Veneers veneers, Veneer veneer)
    {
        return Task.FromResult<dynamic>(null);
    }

    protected virtual Task<dynamic> OnDataArrivalAsync(Veneers veneers, Veneer veneer, dynamic beforeArrival)
    {
        return Task.FromResult<dynamic>(null);
    }

    protected virtual Task AfterDataArrivalAsync(Veneers veneers, Veneer veneer, dynamic onArrival)
    {
        return Task.CompletedTask;
    }

    public virtual async Task OnDataChangeInternalAsync(Veneers veneers, Veneer veneer)
    {
        var beforeRet = await BeforeDataChangeAsync(veneers, veneer);
        var onRet = await OnDataChangeAsync(veneers, veneer, beforeRet);
        await AfterDataChangeAsync(veneers, veneer, onRet);
    }

    protected virtual Task<dynamic> BeforeDataChangeAsync(Veneers veneers, Veneer veneer)
    {
        return Task.FromResult<dynamic>(null);
    }

    protected virtual Task<dynamic> OnDataChangeAsync(Veneers veneers, Veneer veneer, dynamic beforeChange)
    {
        return Task.FromResult<dynamic>(null);
    }

    protected virtual Task AfterDataChangeAsync(Veneers veneers, Veneer veneer, dynamic onChange)
    {
        return Task.CompletedTask;
    }

    public virtual async Task OnErrorInternalAsync(Veneers veneers, Veneer veneer)
    {
        var beforeRet = await BeforeDataErrorAsync(veneers, veneer);
        var onRet = await OnErrorAsync(veneers, veneer, beforeRet);
        await AfterDataErrorAsync(veneers, veneer, onRet);
    }

    protected virtual Task<dynamic> BeforeDataErrorAsync(Veneers veneers, Veneer veneer)
    {
        return Task.FromResult<dynamic>(null);
    }

    protected virtual Task<dynamic> OnErrorAsync(Veneers veneers, Veneer veneer, dynamic beforeError)
    {
        return Task.FromResult<dynamic>(null);
    }

    protected virtual Task AfterDataErrorAsync(Veneers veneers, Veneer veneer, dynamic onError)
    {
        return Task.CompletedTask;
    }

    public virtual async Task OnStrategySweepCompleteInternalAsync()
    {
        var beforeRet = await BeforeSweepCompleteAsync(Machine);
        var onRet = await OnStrategySweepCompleteAsync(Machine, beforeRet);
        await AfterSweepCompleteAsync(Machine, onRet);
    }

    protected virtual Task<dynamic> BeforeSweepCompleteAsync(Machine machine)
    {
        return Task.FromResult<dynamic>(null);
    }

    protected virtual Task<dynamic> OnStrategySweepCompleteAsync(Machine machine, dynamic beforeSweepComplete)
    {
        return Task.FromResult<dynamic>(null);
    }

    protected virtual Task AfterSweepCompleteAsync(Machine machine, dynamic onSweepComplete)
    {
        return Task.CompletedTask;
    }

    public virtual Task OnGenerateIntermediateModelAsync(dynamic model)
    {
        return Task.CompletedTask;
    }
}